package razor.blade;

import javafx.beans.binding.*;
import javafx.scene.*;
import javafx.scene.paint.*;
import javafx.scene.shape.*;
import javafx.beans.property.*;
import javafx.beans.value.*;
import javafx.scene.control.*;
import tee.binding.*;

public class ScrollBox {
    private Numeric x;
    private Numeric y;
    private Numeric height;
    private Numeric width;
    private Group root;
    private Group contentGroup;
    private Group lassoGroup;
    private Group node;
    private Lasso lasso;
    public Node node() {
        return node;
    }
    public ScrollBox content(Node n) {
        lassoGroup.getChildren().clear();
        lassoGroup.getChildren().add(n);
        return this;
    }
    public ScrollBox() {
	final ScrollBox me=this;
        x = new Numeric().value(0);
        y = new Numeric().value(0);
        height = new Numeric().value(100);
        width = new Numeric().value(100);
        root = new Group();
        
        /*Rectangle r1 = new Rectangle();
        r1.xProperty().bind(new Tee<Double>(x));
        r1.yProperty().bind(new Tee<Double>(y));
        r1.heightProperty().bind(new Tee<Double>(height));
        r1.widthProperty().bind(new Tee<Double>(width));
        Stop[] stops1 = new Stop[]{new Stop(0, Color.web("#ff0000")), new Stop(1, Color.web("#ffffff"))};
        LinearGradient fill1 = new LinearGradient(0, 0, 1, 1, true, CycleMethod.NO_CYCLE, stops1);
        r1.setFill(fill1);
        root.getChildren().add(r1);*/
        
        
        lassoGroup = new Group();
        contentGroup = new Group();
        contentGroup.translateXProperty().bind(new Tee<Double>(x));
        contentGroup.translateYProperty().bind(new Tee<Double>(y));
        Rectangle cntClip = new Rectangle();
	cntClip.widthProperty().bind(new Tee<Double>(width));
	cntClip.heightProperty().bind(new Tee<Double>(height));
	contentGroup.setClip(cntClip);
        lasso=new Lasso().content(lassoGroup);
        contentGroup.getChildren().add(lasso.node());
        root.getChildren().add(contentGroup);
        Numeric vshift=new Numeric().value(0);
        Numeric hshift=new Numeric().value(0);
        lassoGroup.translateYProperty().bind(new Tee<Double>(vshift.multiply(-1).multiply(lasso.height()).divide(height)));
        lassoGroup.translateXProperty().bind(new Tee<Double>(hshift.multiply(-1).multiply(lasso.width()).divide(width)));
        root.getChildren().add(new ScrollVertical()
                .x(x.plus(width).minus(14))
                .y(y)
                .height(height)
                .contentHeight(lasso.height())
                .shift(vshift)
                .node());
	/*lasso.width().afterChange(new Task(){
	    @Override public void doTask() {
		System.out.println("lasso.width(): "+lasso.width().value());
	    }
	});*/
        root.getChildren().add(new ScrollHorizontal()
                .x(x)
                .y(y.plus(height).minus(14))
                .width(width.read())
                .contentWidth(lasso.width().read())
                .shift(hshift)
                .node());
        node = new Group();
        node.getChildren().add(root);
        
    }
    public ScrollBox x(double it) {
        x.value(it);
        return this;
    }
    public ScrollBox x(int it) {
        x.value(it);
        return this;
    }
    public Numeric x() {
        return x;
    }
    public ScrollBox x(It<Double> it) {
        x.bind(it);
        return this;
    }
    public ScrollBox y(double it) {
        y.value(it);
        return this;
    }
    public ScrollBox y(int it) {
        y.value(it);
        return this;
    }
    public Numeric y() {
        return y;
    }
    public ScrollBox y(It<Double> it) {
        y.bind(it);
        return this;
    }
    public ScrollBox width(double it) {
        width.value(it);
        return this;
    }
    public ScrollBox width(int it) {
        width.value(it);
        return this;
    }
    public Numeric width() {
        return width;
    }
    public ScrollBox width(It<Double> it) {
        width.bind(it);
        return this;
    }
    public ScrollBox height(double it) {
        height.value(it);
        return this;
    }
    public ScrollBox height(int it) {
        height.value(it);
        return this;
    }
    public Numeric height() {
        return height;
    }
    public ScrollBox height(It<Double> it) {
        height.bind(it);
        return this;
    }
}
